package com.zjy.basic.service.impl;

import com.zjy.basic.commonenum.ErrorCode;
import com.zjy.basic.constant.Constant;
import com.zjy.basic.domain.dto.SmsDto;
import com.zjy.basic.exception.CustomException;
import com.zjy.basic.service.VerifyCodeService;
import com.zjy.basic.util.AjaxResult;
import com.zjy.basic.util.StrUtils;
import com.zjy.basic.util.VerifyCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements VerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 获取图形验证码
     * @param imageCodeKey
     * @return
     */
    @Override
    public AjaxResult getImageCode(String imageCodeKey) {
        //获取随机复杂字符串(使用工具类StrUtils.java)
        String code = StrUtils.getComplexRandomString(4);
        //获取图形验证码(使用工具类VerifyCodeUtils.java)
        String verifyCode = VerifyCodeUtils.VerifyCode(115, 40, code);
        //保存在redis，并设置过期时间
        redisTemplate.opsForValue().set(imageCodeKey,code,5, TimeUnit.MINUTES);
        return AjaxResult.me().setResultObj(verifyCode);
    }

    @Override
    public AjaxResult sendSmsCode(SmsDto dto) {
        //一.空值校验(这一步直接在实体类里加注解)
        //二.图形验证码校验(是否正确)
        //从redis中获取图形验证码
        String imageCode = (String)redisTemplate.opsForValue().get(dto.getImageCodeKey());
        //如果没有（业务异常）
        if (imageCode==null){
            throw new CustomException(ErrorCode.IMAGE_CODE_TIME_OUT.getCode());
        }
        //通过前端传递的uuid从redis中获取，和传递过来的图形验证码进行比对（忽略大小写）
        if (!imageCode.equalsIgnoreCase(dto.getImageCode())){
            throw new CustomException(ErrorCode.IMAGE_CODE_ERROR.getCode());
        }
        //通过手机号拼接业务键去redis中查询
        String smsKey = dto.getPhone()+ ":" + Constant.REGISTER_KEY;
        String smsCodeValue = (String)redisTemplate.opsForValue().get(smsKey);
        //短信验证码已过期或者第一次来获取验证码
        if (smsCodeValue==null){
            //生成验证码
            String smsCode = StrUtils.getRandomString(4);
            //保存redis（设置过期时间3分钟）
            redisTemplate.opsForValue().set(smsKey,smsCode+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
            //调用短信接口发送
            System.out.println("本次获取的验证码>>>>>>" + smsCode);
        }else { //如果是过了一分钟(可以重发)，但是没过三分钟(短信验证码过期)
            //获取旧的过期时间
            Long oldTime = Long.valueOf(smsCodeValue.split(":")[1]);
            //判断是否已过了重发的限制时间(1分钟)
            if (!(System.currentTimeMillis() - oldTime >= 1*60*1000)){//如果没过重发的限制时间
                throw new CustomException("请勿重发点击发送！");
            }
            //剩下的情况就是过了重发的限制时间，可以重新发送短信了，但是为了提升用户体验，我们还是发之前的验证码
            String smsCode = smsCodeValue.split(":")[0];
            //调用短信接口发送
            System.out.println("本次获取的验证码>>>>>>" + smsCode);
            //保存redis刷新过期时间
            redisTemplate.opsForValue().set(smsKey,smsCode+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
        }
        return AjaxResult.me();
    }
}
